package com.woniu.server.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.rabbitmq.client.Address;
import com.woniu.mapper.UserAddreesMapper;
import com.woniu.model.UserAddrees;
import com.woniu.params.AddAddressParam;
import com.woniu.params.ModifyUserAddressParam;
import com.woniu.server.UserAddreesService;
import com.woniu.utils.execption.useraccount.UserAccountExceptionCode;
import com.woniu.utils.execption.useraddress.UserAddressException;
import com.woniu.utils.execption.useraddress.UserAddressExceptionCode;
import com.woniu.utils.utils.RedisKeyUtil;
import com.woniu.utils.utils.RedisUtil;
import com.woniu.utils.utils.StateData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.events.Event;

import java.util.List;
import java.util.stream.Collectors;

import static com.woniu.utils.execption.useraddress.UserAddressExceptionCode.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2024年05月23日
 */
@Service
public class UserAddreesServiceImpl extends ServiceImpl<UserAddreesMapper, UserAddrees> implements UserAddreesService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserAddreesMapper userAddreesMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 用户新增地址
     * @param param
     * @return
     */
    @Override
    public UserAddrees add(AddAddressParam param) {
        //先查询redis
//        if (redisUtil.exist(RedisKeyUtil.userAddressInfo(param.getUserId()+""))){
//            redisUtil.setObject();
//        }
        redisUtil.del(RedisKeyUtil.userAddressInfo(param.getUserId()+""));

        //判断是否存在重复的地址 地址信息和 手机号 以及收货人姓名相同认为重复
        UserAddrees userAddrees = this.getOne(new QueryWrapper<UserAddrees>()
                .eq("user_id", param.getUserId())
                .eq("user_address", param.getUserAddress())
                .eq("phone", param.getPhone())
                .eq("name", param.getName()));
        if (userAddrees!=null) throw new UserAddressException(USER_ADDRESS_EXITS);
        UserAddrees addrees = BeanUtil.toBean(param, UserAddrees.class);
        addrees.setDefaultAddress(StateData.USER_NOT_DEFAULT_ADDRESS);
        addrees.setState(StateData.ADDRESS_STATE_NORMAL);
        save(addrees);
        //使用消息队列保障删除
        rabbitTemplate.convertAndSend("del_user_address_queue",RedisKeyUtil.userAddressInfo(param.getUserId()+""));
        return addrees;
    }

    /**
     * 删除地址信息
     * @param addressId 地址表id
     * @param userId 用户id
     * @return
     */
    @Override
    public UserAddrees del(Integer addressId,int userId) {

        redisUtil.del(RedisKeyUtil.userAddressInfo(userId+""));

        UserAddrees addrees = getById(addressId);
        if (addrees==null) throw new UserAddressException(USER_ADDRESS_NOT_EXITS);
        if (addrees.getUserId().longValue()!=userId) {
            throw new UserAddressException(NOT_DELETE_OTHER_ADDRESS);
        }
        addrees.setState(StateData.ADDRESS_STATE_DELETE);
        updateById(addrees);

        rabbitTemplate.convertAndSend("del_user_address_queue",RedisKeyUtil.userAddressInfo(userId+""));

        return addrees;
    }

    /**
     * 修改地址
     * @param param 修改地址所需的数据
     * @return
     */
    @Override
    public UserAddrees modify(ModifyUserAddressParam param) {
        redisUtil.del(RedisKeyUtil.userAddressInfo(param.getUserId()+""));

        UserAddrees addrees = getById(param.getId());
        if (addrees==null) throw new UserAddressException(USER_ADDRESS_NOT_EXITS);
        if (addrees.getUserId().longValue()!=param.getUserId()) {
            throw new UserAddressException(NOT_MODIFY_OTHER_ADDRESS);
        }
        addrees.setUserAddress(param.getUserAddress());
        addrees.setPhone(param.getPhone());
        addrees.setName(param.getName());
        updateById(addrees);
        rabbitTemplate.convertAndSend("del_user_address_queue",RedisKeyUtil.userAddressInfo(param.getUserId()+""));
        return null;
    }

    /**
     * 用户分页查询地址信息
     * @param pageNum 第几页
     * @param pageSize 每页几条数据
     * @param userId 用户id
     * @return
     */
    @Override
    public Page<UserAddrees> selectPage(Integer pageNum, Integer pageSize, int userId) {
        Page<UserAddrees> page = new Page<>();
        if (redisUtil.exist(RedisKeyUtil.userAddressInfo(userId+""))){
            List<UserAddrees> list =  (List<UserAddrees>) redisUtil.getObject(RedisKeyUtil.userAddressInfo(userId+""));
            page.setTotal(list.size());
            // 获取当前页的数据
            List<UserAddrees> pageContent = list.stream()
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            page.setRecords(pageContent);
            page.setCurrent(pageNum);
            page.setSize(pageSize);
        }else {
            // 如果缓存中不存在，从数据库查询并缓存到 Redis 中
            List<UserAddrees> list = list(new QueryWrapper<UserAddrees>().eq("user_id",userId).eq("state",StateData.ADDRESS_STATE_NORMAL));
            redisUtil.setObject(RedisKeyUtil.userAddressInfo(String.valueOf(userId)), list);
            // 设置总记录数
            page.setTotal(list.size());
            // 获取当前页的数据
            List<UserAddrees> pageContent = list.stream()
                    .skip((pageNum - 1) * pageSize)
                    .limit(pageSize)
                    .collect(Collectors.toList());
            page.setRecords(pageContent);
            page.setSize(pageSize);
        }

        return page;
    }

    /**
     * 设置默认地址
     * @param addressId 地址id
     * @param userId 用户id
     * @return
     */
    @Override
    public UserAddrees settingDefaultAddress(Integer addressId, int userId) {
        UserAddrees userAddrees = getById(addressId);
        if (userAddrees.getUserId().longValue()!=userId) throw new UserAddressException(UserAddressExceptionCode.NOT_MODIFY_OTHER_ADDRESS);
        UserAddrees addrees = getOne(new QueryWrapper<UserAddrees>()
                .eq("default_address", StateData.USER_DEFAULT_ADDRESS)
                .eq("user_id", userId)
        );
        if (addrees!=null){
            addrees.setDefaultAddress(StateData.USER_NOT_DEFAULT_ADDRESS);
            updateById(addrees);
        }
        userAddrees.setDefaultAddress(StateData.USER_DEFAULT_ADDRESS);
        updateById(userAddrees);
        return userAddrees;
    }

}
